#include "../Table.h"
#include <assert.h>
#include <iostream>
#include <map>
#include <set>
using namespace std;
int main()
{
  /* Make sure table can be instanciated. */
  Table t2 = Table(2);
  Table t3 = Table(3);
  Table t4 = Table(4);
  /* Make sure the table has the expected number of players. */
  assert(t2.players.size() == 2);
  assert(t3.players.size() == 3);
  assert(t4.players.size() == 4);
  /* Focus on players=4. */
  assert(t4.players.at(0).getHand()->size() == 3);
  assert(t4.players.at(1).getHand()->size() == 3);
  assert(t4.players.at(2).getHand()->size() == 3);
  assert(t4.players.at(3).getHand()->size() == 3);
  assert(t4.players.at(0).getArmy()->size() == 24);
  assert(t4.players.at(1).getArmy()->size() == 24);
  assert(t4.players.at(2).getArmy()->size() == 24);
  assert(t4.players.at(3).getArmy()->size() == 24);
  for(int i = 0; i < 4; ++i)
  {
    t4.players.at(i).getArmy()->sort();
    t4.players.at(i).getHand()->sort();
  }
  /* Take measurements on the cards to make sure that they are present. */
  set<int> idSet; /* Makes sure no overlapping IDs. */
  map <Rank, int> ranks;
  for(int p = 0; p < t4.players.size(); ++p)
  {
    /* Cards in deck. */
    for(int d = 0; d < t4.players.at(p).getArmy()->size(); ++d)
    {
      Card* deckCard = t4.players.at(p).getArmy()->at(d);
      idSet.insert(deckCard->getID());
      ranks[deckCard->getRank()]++;
    }
    /* Cards in hand. */
    for(int d = 0; d < t4.players.at(p).getHand()->size(); ++d)
    {
      Card* deckCard = t4.players.at(p).getHand()->at(d);
      idSet.insert(deckCard->getID());
      ranks[deckCard->getRank()]++;
    }
  }
  assert(idSet.size() == (13*4+2)*2);
  #if 0
    for(Rank r = joker; r < (Rank)((int)king+1); r=(Rank)((int)r+1))
    {
      cout << "RANK:" << r << " count " << ranks[r] << endl;
    }
  #endif
  assert(ranks[joker] == 4);
  assert(ranks[  ace] == 8);
  assert(ranks[   _2] == 8);
  assert(ranks[   _3] == 8);
  assert(ranks[   _4] == 8);
  assert(ranks[   _5] == 8);
  assert(ranks[   _6] == 8);
  assert(ranks[   _7] == 8);
  assert(ranks[   _8] == 8);
  assert(ranks[   _9] == 8);
  assert(ranks[  _10] == 8);
  assert(ranks[ jack] == 8);
  assert(ranks[queen] == 8);
  assert(ranks[ king] == 8);
  /* Make sure the soloMover is chosen at random. */
  vector<bool> hits;
  for(int i = 0; i < 4; ++i) hits.push_back(false);
  for(int i = 0; i < 100; ++i)
  {
    Table randi(4);
    int findSolo = 0;
    while(&randi.players.at(findSolo) != randi.soloMover) findSolo++;
    hits.at(findSolo) = true;
  }
  assert(hits.at(0) == true);
  assert(hits.at(1) == true);
  assert(hits.at(2) == true);
  assert(hits.at(3) == true);
  /* Make sure you can get active cards. */
  Table actTable(4);
  Card cardA(clubs, _4, 34);
  cardA.setOwner(&actTable.players.at(0));
  Card cardB(clubs, _6, 38);
  cardB.setOwner(&actTable.players.at(2));
  actTable.activeCards.add(&cardA);
  actTable.activeCards.add(&cardB);
  assert(actTable.getCardOf(0).getRank() == _4);
  assert(actTable.getCardOf(1).getRank() == (Rank)15);
  assert(actTable.getCardOf(2).getRank() == _6);
  assert(actTable.getCardOf(3).getRank() == (Rank)15);
  cout << "Table passed tests." << endl;
  return 0;
}
